package com.atguigu.gulimall.gulimall.auth.controller;

import com.atguigu.common.exception.BizCodeEnum;
import com.atguigu.common.utils.R;
import com.atguigu.common.vo.Auth2Resp;
import com.atguigu.common.vo.Auth2RespUserInfo;
import com.atguigu.common.vo.MemberRsepVo;
import com.atguigu.gulimall.gulimall.auth.feign.MemberFeign;
import com.atguigu.gulimall.gulimall.auth.vo.UmsMemberVo;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import javax.annotation.Resource;
import javax.servlet.http.HttpSession;
import javax.validation.Valid;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Controller
public class LoginController {
    @Autowired
    private StringRedisTemplate redisTemplate;
    @Autowired
    private MemberFeign memberFeign;
    @Resource
    private RestTemplate restTemplate;
    @Value("${spring.auth2.clientid}")
    private String clientId;
    @Value("${spring.auth2.clientsecret}")
    private String clientSecret;
    @Value("${spring.auth2.redirecturi}")
    private String redirectUri;

    @ResponseBody
    @GetMapping("/auth/sendCode")
    public R login(String phone) {
        String redisCode = redisTemplate.opsForValue().get(phone);
        String sendCode = UUID.randomUUID().toString().substring(0, 4);
        if (StringUtils.isEmpty(redisCode)) {
            Long current = System.currentTimeMillis();
            redisTemplate.opsForValue().setIfAbsent(phone, sendCode + "_" + current, 15, TimeUnit.MINUTES);
            return R.ok().put("sendCode", sendCode);
        } else {
            String[] s = redisCode.split("_");
            Long currentTime = System.currentTimeMillis();
            if (currentTime - Long.parseLong(s[1]) < 60 * 1000) {
                return R.error().put("msg", BizCodeEnum.SEND_CODE_EXCEPTION.getMsg());
            } else {
                Long current = System.currentTimeMillis();
                redisTemplate.opsForValue().set(phone, sendCode + "_" + current, 15, TimeUnit.MINUTES);
                return R.ok().put("sendCode", sendCode);
            }
        }
    }

    @PostMapping("/auth/register")
    public String register(@Valid UmsMemberVo umsMemberVo, BindingResult bindingResult, RedirectAttributes redirectAttributes) {
        if (bindingResult.hasErrors()) {
            List<FieldError> fieldErrors = bindingResult.getFieldErrors();
            Map<String, String> errorMap = fieldErrors.stream().collect(Collectors.toMap(FieldError::getField, fieldError -> fieldError.getDefaultMessage()));
            redirectAttributes.addFlashAttribute("errors", errorMap);
            return "redirect:http://auth.gulimall.com/reg.html";
        }
        //检验验证码
        String code = umsMemberVo.getCode();
        String redisCode = redisTemplate.opsForValue().get(umsMemberVo.getMobile());
        if (StringUtils.isNotBlank(redisCode)) {
            if (!code.equals(redisCode.split("_")[0])) {
                redirectAttributes.addFlashAttribute("codeErrors", "验证码错误");
                return "redirect:http://auth.gulimall.com/reg.html";
            }
            //删除验证码
            redisTemplate.delete(umsMemberVo.getMobile());
            //调用远程注册服务
            R result = memberFeign.save(umsMemberVo);
            if (result.getCode() == 0) {
                return "redirect:http://auth.gulimall.com/login.html";
            } else {
                Map<String, String> errors = new HashMap<>();
                errors.put("msg", result.getData().toString());
                redirectAttributes.addFlashAttribute("errors", errors);
                return "redirect:http://auth.glmall.com/reg.html";
            }
        } else {
            redirectAttributes.addFlashAttribute("codeErrors", "验证码错误");
            return "redirect:http://auth.gulimall.com/reg.html";
        }

    }

    @PostMapping("/auth/login")
    public String login(UmsMemberVo umsMemberVo, RedirectAttributes redirectAttributes, HttpSession session) {
        MemberRsepVo result = memberFeign.login(umsMemberVo);
        if (result != null) {
            session.setAttribute("loginUser", result);
            return "redirect:http://gulimall.com";
        } else {
            redirectAttributes.addFlashAttribute("loginError", BizCodeEnum.POHNE_NAME_EXCEPTION.getMsg());
            return "redirect:http://auth.glmall.com/login.html";
        }
    }

    @GetMapping("/auth2/success")
    public String success(String code, HttpSession session) {
        String url = "https://api.weibo.com/oauth2/access_token?grant_type=authorization_code&code=" + code + "&client_id=" + clientId + "&redirect_uri=" + redirectUri + "&client_secret=" + clientSecret;
        MultiValueMap map = new LinkedMultiValueMap();
        map.add("grant_type", "authorization_code");
        map.add("code", code);
        map.add("client_id", clientId);
        map.add("redirect_uri", redirectUri);
        map.add("client_secret", clientSecret);
        ResponseEntity<Auth2Resp> auth2RespResponseEntity = restTemplate.postForEntity(url, map, Auth2Resp.class);
        if (auth2RespResponseEntity.getStatusCodeValue() == 200) {
            Auth2Resp auth2Resp = auth2RespResponseEntity.getBody();
            //获取微博登陆用户信息
            String userUrl = "https://api.weibo.com/2/users/show.json?access_token={access_token}&uid={uid}";
            Map<String, String> userMap = new HashMap<>();
            String a = auth2Resp.getAccess_token();
            userMap.put("access_token", auth2Resp.getAccess_token());
            userMap.put("uid", auth2Resp.getUid());
            ResponseEntity<Auth2RespUserInfo> forEntity = restTemplate.getForEntity(userUrl, Auth2RespUserInfo.class, userMap);
            Auth2RespUserInfo auth2RespUserInfo = forEntity.getBody();
            MemberRsepVo memberRsepVo = new MemberRsepVo();
            memberRsepVo.setUsername(auth2RespUserInfo.getName());
            memberRsepVo.setId(auth2RespUserInfo.getId());
            session.setAttribute("loginUser", memberRsepVo);
            return "redirect:http://gulimall.com";
        } else {
            return "redirect:http://auth.gulimall.com";
        }
        //auth2RespResponseEntity
    }


}
